package com.fingard.dsp.bank.directbank.dycb11;

import java.io.BufferedReader;
import java.io.File;
import java.io.StringReader;
import java.text.MessageFormat;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.net.FtpPortClient;
import com.fingard.net.FtpReceiver;
import com.fingard.net.SftpPortClient;
import com.fingard.text.StringHelper;

/**
 * 长城华西银行银保通批量代收付接口
 * 
 * @author Cruise
 * @date 2019/3/19
 */
public class DYCB11BatPayRec extends DYCB11Base implements IBatPayRec {
	@Override
	public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
		return d_BatPayRec(p_req1988);
	}

	@Override
	public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
		return d_QryBatPayRec(p_req1998);
	}

	@Override
	public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
		return d_BatPayRec(p_req9188);
	}

	@Override
	public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
		return d_QryBatPayRec(p_req9198);
	}

	/**
	 * 批量代收付提交
	 * 
	 * <p>功能描述:</p>
	 * <ul>
	 * 	<li>1、文件名命名规则:</li>
	 * 		<li>保险机构编码（2位）+ DYYH + 分行代码（3位）  + DS + YYYYMMDD.TXT
	 * 			保险机构编码（2位）+ DYYH + 分行代码（3位）  + DF + YYYYMMDD.TXT
	 * 		</li>
	 *  <li>2、文件内容格式说明:</li>
	 *  <li>1)  汇总记录：</li>
	 *  	<li>分行代码|汇总笔数|汇总金额|\n</li>
	 *  <li>2)  明细记录：</li>
	 *  	<li>代收标识|业务标记|投保单号|保单号|账号|账号|账户名|金额|证件号|证件类型|流水号|交易日期|申请单编号|分公司代码|分行代码|渠道标志|\n</li>
	 * </ul>
	 * 
	 * @param p_reqBat 批量代收付请求对象
	 * @return 批量代收付响应对象
	 * @throws Exception
	 */
	public RetAtsBatPayRec d_BatPayRec(ReqBatPayRec p_reqBat) throws Exception {
		RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_reqBat.reqHeader);
		retAts.reqSeqID = p_reqBat.reqBatchNO;

		try {
			// 代收付文件内容
			StringBuilder sbFileContent = new StringBuilder();
			
			StringBuilder sbMappingContent = new StringBuilder();

            String tmpPaySendDate = Format.Date8Format.format(getDayCutTime(p_reqBat.getPayDateTime())); 
			// 汇总信息：分行代码|汇总笔数|汇总金额|\n
			//String tmpReqHeader = MessageFormat.format("{0}|{1}|{2}|", bankFront.org, p_reqBat.totalNum, p_reqBat.totalAmt);
			//sbFileContent.append(tmpReqHeader);
			// 文件明细
			String cdFlag = "";
			if (p_reqBat.reqHeader.isBatRec) {
				cdFlag = "DS";
			}else if (p_reqBat.reqHeader.isBatPay) {
				cdFlag = "DF";
			}
			while (p_reqBat.readRecord()) {
				//if (sbFileContent.length() > 0) {
				//	sbFileContent.append("\n");
				//}
				
				//if (sbMappingContent.length() > 0) {
				//	sbMappingContent.append("\n");
				//}
				
				String tmpBusiType = p_reqBat.readedDetail.srcXElement.getSingleText(getBankConfig().getValueAsString("busiTypeForATS"));
				if (StringHelper.hasAnyChar(tmpBusiType)) {
					tmpBusiType = getBankConfig().getMapValueByKey("busiTypeMapping", tmpBusiType);
				}
				if (StringHelper.isNullOrEmpty(tmpBusiType)) {
					if (p_reqBat.reqHeader.isBatRec) {
						tmpBusiType = "122";//122-续期扣款(默认值)
					} else {
						tmpBusiType = "199";//199-其他(默认值)
					}
				}
				
				String sourceNoteCode = p_reqBat.readedDetail.sourceNoteCode;
                if (StringHelper.isNullOrEmpty(sourceNoteCode)) {
                    sourceNoteCode = p_reqBat.readedDetail.memo.trim();
                }
				String ownAct = p_reqBat.ownAct;
				String oppAct = "";
				String oppName = "";
				if (p_reqBat.reqHeader.isBatRec) {
					oppAct = p_reqBat.readedDetail.payAct;
					oppName = p_reqBat.readedDetail.payName;
				} else {
					oppAct = p_reqBat.readedDetail.recAct;
					oppName = p_reqBat.readedDetail.recName;
				}
				String payAmount = p_reqBat.readedDetail.payAmount;
				String certNum = p_reqBat.readedDetail.certNum;
				String certType = convertCertTypeToBank(p_reqBat.readedDetail.certType);
				String postScript = p_reqBat.readedDetail.askNumber;
				String payDate = Format.Date8Format.format(getDayCutTime(p_reqBat.readedDetail.getPayDateTime()));
				String channelFlag = getBankConfig().getValueAsString("channelFlag");
				
				// 明细信息:0代收标识|1业务标记|2投保单号|3保单号|4账号|5账号|6账户名|7金额|8证件号|9证件类型|10流水号|11交易日期|12申请单编号|13分公司代码|14分行代码|15渠道标志\n
				String tmpReqBodyDetail = MessageFormat.format("{0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}|{8}|{9}|{10}|{11}|{12}|{13}|{14}|{15}|\n", 
						cdFlag, tmpBusiType, "", sourceNoteCode, ownAct, oppAct, oppName, payAmount, certNum, certType, postScript, payDate, "", "", bankFront.org , channelFlag);
				sbFileContent.append(tmpReqBodyDetail);
				sbMappingContent.append(postScript + "\n");
			}
			WriteBankLogLn2("批量代收付请求文件内容:\r\n" + sbFileContent.toString());
			
			// 上传文件保存本地: 保险机构编码（2位）+ DYYH + 分行代码（3位）+ DF + YYYYMMDD.TXT

			String tmpUploadFileName = bankFront.corpNo + "DYYH" + bankFront.org + cdFlag + tmpPaySendDate + ".TXT";
			String tmpLocalMarkPath = getTempFileDirectory(getDayCutTime(p_reqBat.getPayDateTime())) + File.separator + tmpUploadFileName;
			String tmpMappingMarkPath = getDataFileDirectory(getDayCutTime(p_reqBat.getPayDateTime())) + File.separator + p_reqBat.reqBatchNO + ".txt";
			
			WriteBankLogLn2("批量代收付请求文件保存本机路径: " + tmpLocalMarkPath);
			

            boolean isSummaryUpload = getBankConfig().getValueAsBool("isSummaryUpload");
            
            if (isSummaryUpload) {//先保存在本地，日切时间15分钟前进行上传
                FileHelper.appendFile(tmpLocalMarkPath, sbFileContent.toString(), getCharset());
                FileHelper.appendFile(tmpMappingMarkPath, sbMappingContent.toString(), getCharset());
                retAts.respCode = "0";
                retAts.respInfo = "上传成功";
                retAts.transState = "Uploaded";
                retAts.payInfoCode = "I4001";
	        }else {//直接上传，一天只能传一个文件
	            if (FileHelper.existFile(tmpLocalMarkPath)) {
	            		retAts.respCode = "0";
	            		retAts.respInfo = "本地批次文件已上传,请勿重复上传!";
	            		retAts.reqSeqID = p_reqBat.reqBatchNO;
	            		retAts.transState = PaymentState.FAIL_Batch;
	            		retAts.payInfoCode = FailCode.E9981;
						retAts.writeRetToATS();
						return retAts;
				}
	            
				String tmpReqHeader = MessageFormat.format("{0}|{1}|{2}|", bankFront.org, p_reqBat.totalNum, p_reqBat.totalAmt);
               
				FileHelper.appendFile(tmpLocalMarkPath, tmpReqHeader+sbFileContent.toString(), getCharset());
                FileHelper.appendFile(tmpMappingMarkPath, sbMappingContent.toString(), getCharset());
                
				// 上送银保通服务器
				FtpSet ftpSet = bankFront.getFtpSet("bat");
				FtpReceiver ftpReceiver = null;
				String requestType = getBankConfig().getValueAsString("requestType");
				if (requestType != null && "SFTP".equals(requestType)) {
					SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
					String sftpFilePath = StringHelper.trimEnd(ftpSet.upDir, "/") + "/" + tmpUploadFileName;
					ftpReceiver = sftpPortClient.uploadFile("", tmpLocalMarkPath, sftpFilePath);
					sftpPortClient.disconnect();
				} else {
					FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
					ftpPortClient.setLocalPassiveMode();
		            ftpReceiver = ftpPortClient.uploadFile(tmpLocalMarkPath, tmpUploadFileName);
		            ftpPortClient.disconnect();
				}
				retAts.respCode = "0";
	            retAts.reqSeqID = p_reqBat.reqBatchNO;
	            if (!ftpReceiver.isCompleted) {
	                retAts.respCode = "-1";
	                retAts.respInfo = ftpReceiver.connMsg;
	            } else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
	            	retAts.respInfo = "上传失败";
	            	retAts.transState = "BatchFailed";
	            	retAts.payInfoCode = "E9999";
	            } else {
	            	retAts.respInfo = "上传成功";
	            	retAts.transState = "Uploaded";
	            	retAts.payInfoCode = "I4001";
	            }
	        }
		} catch (Exception ex) {
			ex.printStackTrace();
			retAts.respCode = "-1";
			retAts.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		} 

		retAts.writeRetToATS();
		return retAts;
	}

	/**
	 * 批量代收付状态查询
	 * 
	 * <p>功能描述:</p>
	 * <ul>
	 * 	<li>1、文件名命名规则:</li>
	 * 		<li>保险机构编码（2位）+ DYYH +分行代码（3位）+DSHP+YYYYMMDD.TXT
	 * 			保险机构编码（2位）+ DYYH +分行代码（3位）+DFHP+YYYYMMDD.TXT
	 * 		</li>
	 *  <li>2、文件内容格式说明:</li>
	 *  <li>1)  汇总记录：</li>
	 *  	<li>分行代码|汇总笔数|汇总金额|\n</li>
	 *  <li>2)  明细记录：</li>
	 *  	<li>0代收标识|1业务标记|2投保单号|3保单号|4账号|5账号|6账户名|7金额|8证件号|9证件类型|10流水号|11交易日期|12申请单编号|13分公司代码|14分行代码|15渠道标志|16处理结果|17返回码|\n</li>
	 * </ul>
	 * 
	 * @param p_reqQryBat
	 * @return
	 * @throws Exception
	 */
	public RetAtsQryBatPayRec d_QryBatPayRec(ReqQryBatPayRec p_reqQryBat) throws Exception {
		RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_reqQryBat.reqHeader);
		retAts.reqSeqID = p_reqQryBat.reqBatchNO;
		
		try {
			// 下载文件名命名规则:保险机构编码（2位）+ DYYH +分行代码（3位）+DSHP+YYYYMMDD.TXT
			String tmpPaySendDate = Format.Date8Format.format(getDayCutTime(p_reqQryBat.getBgnDateTime()));
			String cdFlag = "";
			String tmpMappingMarkPath = getDataFileDirectory(getDayCutTime(p_reqQryBat.getBgnDateTime())) + File.separator + p_reqQryBat.reqBatchNO + ".txt";

			
			if ("9198".equals(p_reqQryBat.reqHeader.transType)) {
				cdFlag = "DSHP";
			} else if (p_reqQryBat.reqHeader.isBatPay){
				cdFlag = "DFHP";
			}
			
			WriteBankLogLn2("是否代扣：" + cdFlag);

			String tmpDownFileName = bankFront.corpNo + "DYYH" + bankFront.org + cdFlag + tmpPaySendDate + ".TXT";
			String tmpLocalMarkPath = createTempFileDirectory(tmpPaySendDate) + File.separator + tmpDownFileName;
			WriteBankLogLn2("批次结果文件保存本地路径: " + tmpLocalMarkPath);

			FtpSet ftpSet = bankFront.getFtpSet("bat");
			FtpReceiver ftpReceiver = null;
			String requestType = getBankConfig().getValueAsString("requestType");
			if (requestType != null && "SFTP".equals(requestType)) {
				String sftpFilePath = StringHelper.trimEnd(ftpSet.downDir, "/") + "/" + tmpDownFileName;
				WriteBankLogLn2("待下载SFTP服务器文件路径:\r\n" + sftpFilePath);
				SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
	            ftpReceiver = sftpPortClient.downloadFile("", sftpFilePath, tmpLocalMarkPath);
	            sftpPortClient.disconnect();
			} else {
				FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
				ftpReceiver = ftpPortClient.downloadFile(tmpDownFileName, tmpLocalMarkPath);
				ftpPortClient.disconnect();
			}
			
			if (ftpReceiver.isCompleted) {
            	String tmpStrRet = FileHelper.readFileText(tmpLocalMarkPath, getCharset());
            	String tmpStrMap = FileHelper.readFileText(tmpMappingMarkPath, getCharset());
            	WriteBankLogLn2("本地批次结果文件内容:\r\n" + tmpStrRet);
            	
            	if (StringHelper.hasAnyChar(tmpStrRet)) {
            		retAts.respCode = "0";
					retAts.reqSeqID = p_reqQryBat.reqBatchNO;
					
					StringReader strReader = new StringReader(tmpStrRet);
					BufferedReader tmpReader = new BufferedReader(strReader);
					tmpReader.readLine();
					
					while(true) {
						String eachline = tmpReader.readLine();
						if(eachline == null){
							break;
						}
						if (eachline.indexOf("|") > 0) {
							// 明细记录:0代收标识|1业务标记|2投保单号|3保单号|4账号|5账号|6账户名|7金额|8证件号|9证件类型|10流水号|11交易日期|12申请单编号|13分公司代码|14分行代码|15渠道标志|16处理结果|17返回码|
							String[] bodyValues = eachline.split("\\|");
							String postScript =  bodyValues[10];
							if(tmpStrMap.contains(postScript + "\n")){
								RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
								
								if(p_reqQryBat.reqHeader.isBatRec){
									tmpRetDetail.recAct = bodyValues[4];
									tmpRetDetail.payAct = bodyValues[5];
									tmpRetDetail.payName = bodyValues[6];
								} else {
									tmpRetDetail.payAct = bodyValues[4];
									tmpRetDetail.recAct = bodyValues[5];
									tmpRetDetail.recName = bodyValues[6];
								}
								tmpRetDetail.postScript = bodyValues[10];
								tmpRetDetail.payAmount = Format.DecimalAmtFormat.format(Double.parseDouble(bodyValues[7]));
								tmpRetDetail.result = bodyValues[17];
								tmpRetDetail.payInfoCode = bodyValues[17];
								tmpRetDetail.memo = bodyValues[16];
		                        
								retAts.writeRetDetail(tmpRetDetail);
							}
						} else {
							retAts.respCode = "-1";
		            		retAts.respInfo = "银行返回明细数据格式非法!";
						}
					}
            	} else {
            		retAts.respCode = "-1";
            		retAts.respInfo = "本地批次结果文件内容为空!";
            	}
            } else {
            	retAts.respCode = "-1";
    			retAts.respInfo = "批次结果文件下载失败:" + ftpReceiver.connMsg;
            }
		} catch (Exception ex) {
			ex.printStackTrace();
			retAts.respCode = "-1";
			retAts.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}
		
		retAts.writeAfterDetail();
		return retAts;
	}
}
